package br.academia.negocio;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


import br.academia.arq.dao.GenericDAO;
import br.academia.arq.erros.DAOException;
import br.academia.arq.erros.NegocioException;
import br.academia.dominio.PersistDB;
import br.academia.dominio.Usuario;
import br.academia.util.Constants;

public abstract class AbstractProcessador<E extends PersistDB> {
	/** Constante de operação de cadastro */
	public static final TipoOperacao CADASTRAR = new TipoOperacao(1);
	
	/** Constante de operação de alterar */
	public static final TipoOperacao ALTERAR = new TipoOperacao(2);
	
	/** Constante de operação de remoção */
	public static final TipoOperacao REMOVER = new TipoOperacao(3);
	
	/**
	 * Método que, dependendo do TipoOperacao passado, decide qual
	 * operação e quais regras de negócio aplicar ao Objeto obj.
	 * @param operacao
	 * @param obj
	 * @throws NegocioException 
	 */
	public abstract void execute(TipoOperacao operacao, E obj) throws NegocioException;

	/**
	 * Retorna a instÂncia do DAO
	 * @param daoClass Herda de GenericDAO
	 * @return A instância do DAO
	 * @throws DAOException
	 */
	public <T extends GenericDAO> T getDAO(Class<T> daoClass)throws DAOException {

		try {
			T dao = daoClass.newInstance();
			return dao;

		} catch (Exception e) {
			throw new DAOException("Erro ao obter DAO " + e.getMessage(), e);
		}

	}
	
	/**
	 * Retorna o usuário logado
	 * @return
	 */
	public Usuario getUsuarioLogado() {
		return (Usuario) getCurrentRequest().getSession().getAttribute(
				Constants.USUARIO_LOGADO);
	}
	
	
	/**
	 * Possibilita o acesso ao HttpServletRequest.
	 */
	public HttpServletRequest getCurrentRequest() {
		return (HttpServletRequest) getExternalContext().getRequest();
	}
	
	/**
	 * Retorna o contexto da aplicação WEB
	 */
	public String getContextPath() {
		return getCurrentRequest().getContextPath();
	}
	
	/**
	 * Possibilita o acesso ao HttpServletResponse.
	 */
	public HttpServletResponse getCurrentResponse() {
		return (HttpServletResponse) getExternalContext().getResponse();
	}
	
	/**
	 * Possibilita o acesso ao HttpSession.
	 */
	public HttpSession getCurrentSession() {
		return getCurrentRequest().getSession(true);
	}
	
	/**
	 * Acessa o external context do JavaServer Faces
	 */
	private ExternalContext getExternalContext() {
		return FacesContext.getCurrentInstance().getExternalContext();
	}

}
